(function($){
	
	var jsonpID = 0,isObject = $.isObject,key;
	
	function empty() {}
	
	$.ajaxJSONP = function(options){
		var jsonpString = 'jsonp' + ++jsonpID,
		script = document.createElement('script');
		window[jsonpString] = function(data){
			options.success(data);
			delete window[jsonpString];
		};
		script.src = options.url.replace(/=\?/, '=' + jsonpString);
		$('head').append(script);
	};
	
	var settings = {
		type: 'GET',
		beforeSend: empty, success: empty, error: empty, complete: empty,
		accepts: {
		script: 'text/javascript, application/javascript',
		json:   'application/json',
		xml:    'application/xml, text/xml',
		html:   'text/html',
		text:   'text/plain'
		}
	};
	
	/*options:{
		type: 'GET', // defaults to 'GET'
		url: '/foo', // defaults to window.location
		data: {name: 'Zepto'}, // can be a string or object (objects are automatically serialized to JSON)
		dataType: 'json', // what response type you accept from the server ('json', 'xml', 'html', or 'text')
		success: function(body) { ... }, // body is a string (or if dataType is 'json', a parsed JSON object)
		error: function(xhr, type) { ... } // type is a string ('error' for HTTP errors, 'parsererror' for invalid JSON)
	}
	*/
	$.ajax = function(options){
		var options = options || {};
		if (!options.url) return;
		var settings = $.extend(settings, options);
		if (/=\?/.test(settings.url)){ return $.ajaxJSONP(settings);}
		if (settings.data && !settings.contentType) settings.contentType = 'application/x-www-form-urlencoded';
		if (isObject(settings.data)) settings.data = $.param(settings.data);
		
		if (settings.type.match(/get/i) && settings.data) {
			var queryString = settings.data;
			if (settings.url.match(/\?.*=/)) {
				queryString = '&' + queryString;
			} else if (queryString[0] != '?') {
				queryString = '?' + queryString;
			}
			settings.url += queryString;
		}
		
		var mime = settings.accepts[settings.dataType],
		xhr = new XMLHttpRequest();
		
		settings.headers = $.extend({'X-Requested-With': 'XMLHttpRequest'}, settings.headers || {});
		
		if (mime) settings.headers['Accept'] = mime;
		
		xhr.onreadystatechange = function(){
			if (xhr.readyState == 4) {
				var result, error = false;
				if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 0) {
					if (mime == 'application/json') {
						try { result = JSON.parse(xhr.responseText); }
						catch (e) { error = e; }
					}else{
						result = xhr.responseText;
					}
					if (error){
						 settings.error(xhr, 'parsererror', error);
					}else{
						 settings.success(result, 'success', xhr);
					}
				} else {
					error = true;
					settings.error(xhr, 'error');
				}
				settings.complete(xhr, error ? 'error' : 'success');
			}
		};
		
		xhr.open(settings.type, settings.url, true);
		if (settings.beforeSend(xhr, settings) === false) {
			xhr.abort();
			return false;
		}
		
		if (settings.contentType) settings.headers['Content-Type'] = settings.contentType;
		for(name in settings.headers) {xhr.setRequestHeader(name, settings.headers[name]);}
		
		xhr.send(settings.data);
		return xhr;
	};
	
	$.get = function(url, success){ $.ajax({ url: url, success: success }) };
	
	$.post = function(url, data, success, dataType){
		if ($.isFunction(data)){
			dataType = dataType || success, success = data, data = null;
		}
		$.ajax({ type: 'POST', url: url, data: data, success: success, dataType: dataType });
	};
	
	$.getJSON = function(url, success){ $.ajax({ url: url, success: success, dataType: 'json' }) };
	
	$.fn.load = function(url, success){
		if (!this.length) return this;
		var self = this, parts = url.split(/\s/), selector;
		if (parts.length > 1) url = parts[0], selector = parts[1];
		$.get(url, function(response){
			self.html(selector ? $(document.createElement('div')).html(response).find(selector).html() : response);
			success && success();
		});
		return this;
	};
	
	$.param = function(obj, v){
		var result = [], isObjArray = $.isArray(obj);
		var add = function(key, value){
			result.push(encodeURIComponent(v ? v + '[' + key + ']' : key)
			+ '=' + encodeURIComponent(value));
		};		
		
		for(key in obj){
			if(isObject(obj[key])){
				result.push($.param(obj[key], (v ? v + '[' + key + ']' : key)));
			}else{
				add(isObjArray ? '' : key, obj[key]);
			}
		}
		return result.join('&').replace('%20', '+');
	};
})(CK);
